package com.xd.demo.wrapper;



import lombok.Setter;
import lombok.Getter;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;


@Getter
@Setter
public class RequestWrapper extends HttpServletRequestWrapper {
    /**
     * 存储请求中的请求体
     */
    private byte[] reqBody;

    public byte[] getReqBody() {
        return reqBody;
    }

    public void setReqBody(byte[] reqBody) {
        this.reqBody = reqBody;
    }

    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        reqBody = readReqBody(request).getBytes(StandardCharsets.UTF_8);
    }

    /**
     * 从指定的request中读取请求体
     *
     * @param request 指定request
     * @return request中的请求体字符串
     * * @throws IOException 请求获取流发生的IO异常
     */
    private String readReqBody(HttpServletRequest request) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        StringBuilder builder = new StringBuilder();
        Scanner scanner = new Scanner(inputStream);
        scanner.forEachRemaining(builder::append);
        return builder.toString();
    }

    /**
     * @return 返回包装好的输入流
     */
    @Override
    public ServletInputStream getInputStream() {
        final ByteArrayInputStream bais = new ByteArrayInputStream(reqBody);
        return new ServletInputStream() {
            @Override
            public int read() {
                return bais.read();
            }

            @Override
            public boolean isFinished() {
                return bais.available() < 1;
            }

            @Override
            public boolean isReady() {
                return true;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }
        };
    }

    @Override
    public BufferedReader getReader() {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
}
